package com.gopay.bis.manager.bank.Wap;

import java.util.Map;

import javax.annotation.Resource;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.TransUtil;
import com.gopay.common.domain.bank.BaseMessage;
import com.gopay.common.domain.bank.spdb.ebank.SpdbMessage;
import com.gopay.common.exception.GopayException;
import com.gopay.remote.bank.WapPayManagerRemoteService;
import com.gopay.remote.bank.businesses.BankService;

/**
 * 浦发银行wap支付B2C对象封装
 * @author xiaojian
 */
public class SpdbWapB2cManager implements WapPayManagerRemoteService {

	@Resource(name = "spdbConfig")
	private Map<String, String> spdbConfig;
	
	@Resource(name = "spdbB2cBankServiceClient")
	private BankService spdbB2cBankServiceClient;

	@Override
	public Object sign(BaseMessage msg) throws GopayException {
		SpdbMessage message = (SpdbMessage) msg;
		message.setBankOrderId(TransUtil.processOrderIdTo12Digit(msg.getOrderId()));
		message.setBankUrl(message.getPayUrl());
		message.setTranAbbr((String) spdbConfig.get("SPDB.B2C.TRANABBR"));
		message.setTermCode((String) spdbConfig.get("SPDB.TERMCODE"));
		message.setMercCode(message.getMerID());
		message.setMercUrl(message.getPayRuturnUrl());
		message.setIp((String) spdbConfig.get("SPDB.B2C.IP"));
		String plainMessage = buildMessage(message);
		message.setPlainMessage(plainMessage);
		BankLogUtils.printB2CManagerSignSendLog(message);
		String signMessage;
		signMessage = (String) this.spdbB2cBankServiceClient.sign(message);
		message.setSignMessage(signMessage);
		BankLogUtils.printB2CManagerSignReturnLog(message);
		return message;
	}

	@Override
	public Object verify(BaseMessage baseMessage) throws GopayException {
		SpdbMessage message = (SpdbMessage) baseMessage;
		BankLogUtils.printB2CVerifyPlainLog(baseMessage);
		BankLogUtils.printB2CVerifySignatureLog(baseMessage, message.getSignMessage());
		boolean isVerify;
		isVerify = (Boolean) this.spdbB2cBankServiceClient.verify(message);
		BankLogUtils.printB2CVerifyResultLog(baseMessage, isVerify);
		return isVerify;
	}

	public Object query(Object obj) throws GopayException {
		SpdbMessage message = (SpdbMessage) obj;
		message.setTermCode((String) spdbConfig.get("SPDB.TERMCODE"));
		message.setMercCode(message.getMerID());
		message.setTransName((String) spdbConfig.get("SPDB.TRANABBR.QUERY"));
		message.setoTranAbbr((String) spdbConfig.get("SPDB.B2C.TRANABBR"));
		message.setTermSsn(message.getBankOrderId());
		message.setPlainMessage(buildQuery(message));
		BankLogUtils.printB2CManagerQuerySendLog(message, message);
		message = (SpdbMessage) this.spdbB2cBankServiceClient.query(message);
		BankLogUtils.printB2CManagerQueryReturnLog(message);
		return message;
	}

	/**
	 * 构建报文
	 * @param message
	 * @return String spdbMessage
	 */
	private String buildMessage(SpdbMessage message) {
		// 组织明文串
		StringBuffer sb = new StringBuffer();
		sb.append("TranAbbr=").append(message.getTranAbbr()).append("|");
		sb.append("MercDtTm=").append(message.getOrderDate()).append("|");
		sb.append("TermSsn=").append(message.getBankOrderId()).append("|");
		sb.append("OSttDate=").append(message.getoSttDate()).append("|");
		sb.append("OAcqSsn=").append(message.getoAcqSsn()).append("|");
		sb.append("MercCode=").append(message.getMercCode()).append("|");
		sb.append("TermCode=").append(message.getTermCode()).append("|");
		sb.append("TranAmt=").append(message.getAmount().toString()).append("|");
		sb.append("Remark1=").append(message.getRemark1()).append("|");
		sb.append("Remark2=").append(message.getRemark2()).append("|");
		sb.append("MercUrl=").append(message.getMercUrl()).append("|");
		sb.append("Ip=").append(message.getIp());
		return sb.toString();
	}

	private String buildQuery(SpdbMessage message) {
		StringBuffer sb = new StringBuffer();
		sb.append("MercCode=").append(message.getMercCode()).append("|");
		sb.append("OTranAbbr=").append(message.getoTranAbbr()).append("|");
		sb.append("TermSsn=").append(message.getBankOrderId());
		return sb.toString();
	}

	public Object dayend(BaseMessage base) throws GopayException, Exception {
		return null;
	}

}
